﻿using Microsoft.EntityFrameworkCore.Metadata.Internal;
using System.ComponentModel.DataAnnotations;
using System.Reflection;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using ValidationResult = System.ComponentModel.DataAnnotations.ValidationResult;
namespace MyProject.Core
{
    public static class ValidationHelper
    {
        public static bool IsFormValid(object model, FrameworkElement? page, string? classSuffix = null)
        {
            HideValidationFields(model, page, "_Error", classSuffix);
            var errors = new List<ValidationResult>();
            var context = new ValidationContext(model);
            bool isValid = Validator.TryValidateObject(model, context, errors, true);
            if (!isValid && page != null)
            {
                ShowValidationFields(errors, model, page, "_Error", classSuffix);
            }
            return errors.Count() == 0;
        }

        public static List<ValidationResult>? getFormErrors(object model)
        {
            var errors = new List<ValidationResult>();
            var context = new ValidationContext(model);
            Validator.TryValidateObject(model, context, errors, true);
            return errors.Count() > 0 ? errors : null;
        }

        private static void HideValidationFields
            (object model, FrameworkElement? page, string validationLabelSuffix = "_Error", string? classSuffix = null)
        {
            if (model == null || page == null) { 
                return; 
            }

            var properties = GetValidatablePropertyNames(model, classSuffix);
            foreach (var propertyName in properties)
            {
                var errorControlName =
                $"{propertyName.Replace(".", "_")}{validationLabelSuffix}";
                var control = page.FindName(errorControlName);
                if (control != null && control.GetType() == typeof(Label))
                {
                    var label = (Label)control;
                    label.Visibility = System.Windows.Visibility.Collapsed;
                }

                var textControl = page.FindName($"{propertyName.Replace(".", "_")}");

                if (textControl == null)
                {
                    return;
                }

                switch (textControl.GetType().Name)
                {
                    case "TextBox":
                        var Control = (Control)textControl;
                        Control.BorderBrush = new BrushConverter().ConvertFrom("#FFACACAC") as System.Windows.Media.Brush;
                        break;
                    case "DatePicker":
                    case "ComboBox":
                        var border = page.FindName($"{propertyName.Replace(".", "_")}_border");
                        if (border != null)
                        {
                            ((Border)border).BorderBrush = new BrushConverter().ConvertFrom("#FFACACAC") as System.Windows.Media.Brush;
                        }
                        
                        break;
                }
            }
        }
        private static void ShowValidationFields
        (List<System.ComponentModel.DataAnnotations.ValidationResult> errors,
        object model, FrameworkElement page, string validationLabelSuffix = "_Error", string? classSuffix = null)
        {
            if (model == null) { return; }
            string cSuffix = classSuffix != null ? classSuffix : "";
            foreach (var error in errors)
            {
                var memberName = $"{model.GetType().Name}{cSuffix}_{error.MemberNames.FirstOrDefault()}";
                memberName = memberName.Replace(".", "_");
                var errorControlName = $"{memberName}{validationLabelSuffix}";
                var control = page.FindName(errorControlName);
                if (control != null && control.GetType() == typeof(Label))
                {
                    var label = (Label)control;
                    label.Content = $"{error.ErrorMessage}{Environment.NewLine}";
                    label.Visibility = System.Windows.Visibility.Visible;
                }

                var textControl = page.FindName(memberName);

                switch (textControl.GetType().Name)
                {
                    case "TextBox":
                        var Control = (Control)textControl;
                        Control.BorderBrush = new BrushConverter().ConvertFrom("#FFF50000") as System.Windows.Media.Brush;
                        break;
                    case "DatePicker":
                    case "ComboBox":
                        var border = page.FindName($"{memberName.Replace(".", "_")}_border");
                        if (border != null)
                        {
                            ((Border)border).BorderBrush = new BrushConverter().ConvertFrom("#FFF50000") as System.Windows.Media.Brush;
                        }
                        break;
                }
            }
        }
        private static IEnumerable<string> GetValidatablePropertyNames(object model, string? classSuffix = null)
        {
            var validatableProperties = new List<string>();
            var properties = GetValidatableProperties(model);
            string cSuffix = classSuffix != null ? classSuffix : "";
            foreach (var propertyInfo in properties)
            {
                var errorControlName = $"{propertyInfo.DeclaringType.Name}{cSuffix}.{propertyInfo.Name}";
                validatableProperties.Add(errorControlName);
            }
            return validatableProperties;
        }
        private static List<PropertyInfo> GetValidatableProperties(object model)
        {
            var properties = model.GetType().GetProperties().Where(prop => prop.CanRead
                && prop.GetCustomAttributes(typeof(ValidationAttribute), true).Any()
                && prop.GetIndexParameters().Length == 0).ToList();
            return properties;
        }
    }
}
